//    Copyright (C) Kherty.  All rights reserved.
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Reflection;
using OpenLS.Core.Serialization;

namespace OpenLS.Spreadsheet
{
    public class SortState : IOfficeXmlSerializable, INotifyPropertyChanged
    {
        public SortState()
        {

        }
        public SortState(Range range)
        {
            _range = range;
        }
        #region IOfficeXmlSerializable Members

        void IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            using (ReadContext c = context.Read("sortState"))
            {
                columnSort = c.GetOptionalBoolean("columnSort", false);
                IsCaseSensitive = c.GetOptionalBoolean("caseSensitive", false);
                sortMethod = c.GetOptionalEnum("sortMethod", SortMethod.None);
                Worksheet ws = context.GetData<Worksheet>();
                Reference = c.GetString("ref");
                Range = ws.GetRange(Reference);
                SortConditions.Clear();
                while (c.ReaderLocalName == "sortCondition")
                {
                    SortCondition co = new SortCondition(this);
                    ((IOfficeXmlSerializable)co).ReadXml(c);
                    SortConditions.Add(co);
                }
            }
        }

        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            using (WriteContext c = context.Write("sortState"))
            {
                c.SetOptionalBoolean("columnSort", columnSort, false);
                c.SetOptionalBoolean("caseSensitive", IsCaseSensitive, false);
                c.SetOptionalEnum("sortMethod", sortMethod, SortMethod.None);
                c.SetString("ref", Reference);
                foreach (SortCondition co in SortConditions)
                    c.WriteElement(co);
            }
        }

        #endregion
        private Range _range;

        public Range Range
        {
            get { return _range; }
            set { _range = value; }
        }
	
        private bool columnSort;

        public bool SortByColumn
        {
            get { return columnSort; }
            set { columnSort = value; notifyPropertyChanged("SortByColumn"); }
        }
        private bool caseSensitive;

        public bool IsCaseSensitive
        {
            get { return caseSensitive; }
            set { caseSensitive = value; }
        }
        private SortMethod sortMethod;

        public SortMethod SortMethod
        {
            get { return sortMethod; }
            set { sortMethod = value; }
        }
        private string _ref;

        public string Reference
        {
            get { return _ref; }
            set { _ref = value; }
        }
        private readonly ObservableCollection<SortCondition> _sortConditions = new ObservableCollection<SortCondition>();

        public ObservableCollection<SortCondition> SortConditions
        {
            get { return _sortConditions; }
        }





        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        void notifyPropertyChanged(string propertyName)
        {
            Contract.Requires(GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null);
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        internal int Compare(PartialRowOrColumnRange r1, PartialRowOrColumnRange r2)
        {
            foreach (SortCondition condition in SortConditions)
            {
                int i = condition.Compare(r1, r2);
                if (i != 0)
                    return i;
            }
            return 0;
        }


    }
}
